package com.itheima.reggie.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.reggie.entity.*;
import com.itheima.reggie.entity.dto.DishDto;
import com.itheima.reggie.exception.CustomerException;
import com.itheima.reggie.mappers.CategoryMapper;
import com.itheima.reggie.mappers.DishFlavorMapper;
import com.itheima.reggie.mappers.DishMapper;
import com.itheima.reggie.service.DishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class DishServiceImpl implements DishService {
    @Autowired(required = false)
    private DishMapper dishMapper;

    @Autowired(required = false)
    private DishFlavorMapper dishFlavorMapper;

    @Autowired(required = false)
    private CategoryMapper categoryMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void save(DishDto dishDto) {
        dishDto.setCreateTime(LocalDateTime.now());
        dishDto.setUpdateTime(LocalDateTime.now());

        dishDto.setSort(0);

        dishMapper.save(dishDto);

        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setCreateUser(dishDto.getCreateUser());
            flavor.setUpdateUser(dishDto.getUpdateUser());
            flavor.setCreateTime(LocalDateTime.now());
            flavor.setUpdateTime(LocalDateTime.now());
            flavor.setDishId(dishDto.getId());
        }

        dishFlavorMapper.save(flavors);

        //清理所有菜品的缓存数据
        Set keys = redisTemplate.keys("dish_*"); //获取所有以dish_xxx开头的key
        redisTemplate.delete(keys); //删除这些key
    }

    @Override
    public R<Page<DishDto>> findByPage(Integer page, Integer pageSize, String name) {
        PageHelper.startPage(page, pageSize); //分页放在第一行，下面的对象有page属性

        List<Dish> dishList = dishMapper.findByName(name);


        // 根据名字查询菜品的列表  List<Dish>, 把List<Dish>--List<DishDto>
        PageInfo<Dish> pageInfo = new PageInfo<>(dishList);

        // 把Dish转换为DishDTO
        /*List<DishDto> dishDtoList = new ArrayList<>();
        for (Dish dish : dishList) {
            DishDto dishDto = new DishDto();
            // 属性拷贝，属性拷贝的前提：属性名与属性的类型要完全一致
            BeanUtils.copyProperties(dish, dishDto);

            // 根据类别的id查找类别
            Category category = categoryMapper.findById(dish.getCategoryId());

            dishDto.setCategoryName(category.getName());
            dishDtoList.add(dishDto);
        }*/

        List<DishDto> dishDtoList = pageInfo.getList().stream().map(dish -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(dish, dishDto);
            Category category = categoryMapper.findById(dish.getCategoryId());

            dishDto.setCategoryName(category.getName());
            return dishDto;
        }).collect(Collectors.toList());

        Page<DishDto> pageResult = new Page<>(dishDtoList, pageInfo.getTotal(), page, pageSize);

        return R.success(pageResult);
    }

    @Override
    public R<DishDto> findById(Long id) {
        //通过id查找一个菜品
        Dish dish = dishMapper.findById(id);

        //通过dishId查找菜品对应的口味
        List<DishFlavor> dishFlavors = dishFlavorMapper.findByDishId(id);

        //把Dish转换为DishDTo，并且要往Dto设置口味信息
        DishDto dishDto = new DishDto();
        BeanUtils.copyProperties(dish, dishDto);
        dishDto.setFlavors(dishFlavors);

        return R.success(dishDto);
    }

    @Override
    public void updateWithFlavor(DishDto dishDto) {
        //1. 补全修改时间
        dishDto.setUpdateTime(LocalDateTime.now());

        //2 修改菜品
        dishMapper.update(dishDto);

        //3. 删除该菜品的所有口味信息
        // dishFlavorMapper.delete(dishDto.getId());
        dishFlavorMapper.delete(new Long[]{dishDto.getId()});

        //4. 补全口味信息，然后重新插入
        List<DishFlavor> flavors = dishDto.getFlavors();
        List<DishFlavor> dishFlavorList = flavors.stream().map((flavor -> {
            flavor.setDishId(dishDto.getId());
            flavor.setCreateUser(dishDto.getCreateUser());
            flavor.setUpdateUser(dishDto.getUpdateUser());
            flavor.setCreateTime(LocalDateTime.now());
            flavor.setUpdateTime(LocalDateTime.now());
            return flavor;
        })).collect(Collectors.toList());

        //4. 批量保存口味信息
        dishFlavorMapper.save(dishFlavorList);
    }

    @Override
    public R<List<DishDto>> findByCategoryId(Long categoryId, Integer status) {

        // 获取缓存的数据
        String key = "dish_" + categoryId + "_" + status;
        ValueOperations valueOperations = redisTemplate.opsForValue();
        List<DishDto> dishDtoList = (List<DishDto>) valueOperations.get(key);

        //如果为空，则存入用数据库查询，并且存入缓存
        if (dishDtoList == null) {
            List<Dish> dishList = dishMapper.findByCategoryId(categoryId, status);

            dishDtoList = dishList.stream().map(dish -> {
                DishDto dishDto = new DishDto();
                BeanUtils.copyProperties(dish, dishDto);
                // 通过菜品的id查询口味的数据
                List<DishFlavor> dishFlavors = dishFlavorMapper.findByDishId(dish.getId());
                dishDto.setFlavors(dishFlavors);
                // 类别信息
                Category categoryName = categoryMapper.findById(dish.getCategoryId());
                dishDto.setCategoryName(categoryName.getName());
                return dishDto;
            }).collect(Collectors.toList());

            valueOperations.set(key,dishDtoList);
        }

        return R.success(dishDtoList);
    }

    @Override
    public void delete(Long[] ids) {
        //查询菜品是否在售
        Integer count = dishMapper.findCountById(ids);
        if (count > 0) {
            throw new CustomerException("请勿删除在售商品");
        }

        //删除菜品
        dishMapper.delete(ids);

        //删除菜品对应口味
        dishFlavorMapper.delete(ids);
    }

    @Override
    public void updateStatus(List<Long> ids, int status) {
        dishMapper.updateStatus(ids, status);
    }

}
